package com.aps.algorithm.core;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 算法执行上下文
 * 用于在算法执行过程中传递和存储上下文信息
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AlgorithmContext {
    
    /**
     * 上下文数据
     */
    private Map<String, Object> contextData = new HashMap<>();
    
    /**
     * 算法执行指标
     */
    private List<AlgorithmMetric> metrics = new ArrayList<>();
    
    /**
     * 算法开始时间
     */
    private LocalDateTime startTime;
    
    /**
     * 算法结束时间
     */
    private LocalDateTime endTime;
    
    /**
     * 算法执行状态
     */
    private AlgorithmStatus status = AlgorithmStatus.PENDING;
    
    /**
     * 错误信息
     */
    private String errorMessage;
    
    /**
     * 添加上下文数据
     * @param key 键
     * @param value 值
     */
    public void addContextData(String key, Object value) {
        contextData.put(key, value);
    }
    
    /**
     * 获取上下文数据
     * @param key 键
     * @param defaultValue 默认值
     * @return 值
     */
    @SuppressWarnings("unchecked")
    public <T> T getContextData(String key, T defaultValue) {
        return (T) contextData.getOrDefault(key, defaultValue);
    }
    
    /**
     * 获取上下文数据
     * @param key 键
     * @return 值
     */
    public Object getContextData(String key) {
        return contextData.get(key);
    }
    
    /**
     * 添加执行指标
     * @param name 指标名称
     * @param value 指标值
     */
    public void addMetric(String name, double value) {
        metrics.add(new AlgorithmMetric(name, value, LocalDateTime.now()));
    }
    
    /**
     * 获取指标值
     * @param name 指标名称
     * @return 指标值
     */
    public double getMetric(String name) {
        return metrics.stream()
            .filter(m -> m.getName().equals(name))
            .mapToDouble(AlgorithmMetric::getValue)
            .findFirst()
            .orElse(0.0);
    }
    
    /**
     * 获取所有指标
     * @return 指标列表
     */
    public List<AlgorithmMetric> getAllMetrics() {
        return new ArrayList<>(metrics);
    }
    
    /**
     * 设置开始时间
     */
    public void setStartTime() {
        this.startTime = LocalDateTime.now();
        this.status = AlgorithmStatus.RUNNING;
    }
    
    /**
     * 设置结束时间
     */
    public void setEndTime() {
        this.endTime = LocalDateTime.now();
        this.status = AlgorithmStatus.COMPLETED;
    }
    
    /**
     * 设置错误状态
     * @param errorMessage 错误信息
     */
    public void setError(String errorMessage) {
        this.errorMessage = errorMessage;
        this.status = AlgorithmStatus.ERROR;
        this.endTime = LocalDateTime.now();
    }
    
    /**
     * 获取执行时间（毫秒）
     * @return 执行时间
     */
    public long getExecutionTimeMillis() {
        if (startTime == null || endTime == null) {
            return 0;
        }
        return java.time.Duration.between(startTime, endTime).toMillis();
    }
    
    /**
     * 算法执行状态枚举
     */
    public enum AlgorithmStatus {
        PENDING,    // 等待执行
        RUNNING,    // 正在执行
        COMPLETED,  // 执行完成
        ERROR       // 执行错误
    }
}
